import { ModalForm } from '@ant-design/pro-components';
import { message, Table, Tag, Tooltip } from 'antd';
import React, { useEffect, useState } from 'react';
import { RoleType } from './roleForm';
import { queryAllResource, queryRoleResourceList, updateRoleResource } from '@/services/system/SystemController';
import { useRequest } from '@umijs/max';
import ResultWrap from '@/components/ResultWrap';

type MethodSelect = { get: boolean, put: boolean, post: boolean, delete: boolean }
type ResourceSelect = Record<number, MethodSelect>;

const allMethod: MethodSelect = { get: true, post: true, put: true, delete: true }
function methods_to_string(method: MethodSelect) {
  let methods = []
  if (method.get) { methods.push("GET") }
  if (method.post) { methods.push("POST") }
  if (method.put) { methods.push("PUT") }
  if (method.delete) { methods.push("DELETE") }
  return methods.join("|")
}

function methods_is_select(method: MethodSelect) {
  return method.get || method.post || method.put || method.delete
}

function string_to_methods(s: String) {
  return {
    get: s.indexOf("GET") >= 0,
    post: s.indexOf("POST") >= 0,
    put: s.indexOf("PUT") >= 0,
    delete: s.indexOf("DELETE") >= 0
  }
}

const RoleResourceForm: React.FC<{
  data: RoleType | null;
  onClose: () => void;
  onFinish: () => void;
}> = ({ data, onClose, onFinish }) => {
  const [selectedRowKeys, setSelectedRowKeys] = useState<number[]>([]);
  const [sMethod, setsMethod] = useState<ResourceSelect>({})
  // 加载数据
  let { data: resources, run: loadRoleResourceList, loading, error } = useRequest((id: number | undefined) => Promise.all([queryAllResource(), queryRoleResourceList(id)]), {
    manual: true,
    onSuccess(data, params) {
      let s: ResourceSelect = {}
      data[1].forEach((v) => { s[v.resource_id] = string_to_methods(v.method) })
      setsMethod(s)
      setSelectedRowKeys(data[1].map((d) => d.resource_id));
    },
  });
  // 提交数据
  let { run: update, loading: updating } = useRequest(() => {
    return data ? updateRoleResource(data.id, selectedRowKeys
      .filter(id => sMethod[id] && (sMethod[id].get || sMethod[id].post || sMethod[id].put || sMethod[id].delete))
      .map(id => ({ resource_id: id, method: methods_to_string(sMethod[id]) }))) : Promise.reject("null id")
  }, {
    manual: true,
    throwOnError: true,
    onError(e) { console.log(e) },
    onSuccess(data, params) {
      message.success("操作成功")
      onFinish()
    },
  })
  useEffect(() => { data ? loadRoleResourceList(data.id) : setSelectedRowKeys([]) }, [data])
  function click_method(id: number, v: boolean, type: "get" | "put" | "post" | "delete") {
    sMethod[id] = { get: sMethod[id]?.get || false, post: sMethod[id]?.post || false, put: sMethod[id]?.put || false, delete: sMethod[id]?.delete || false }
    sMethod[id][type] = v;
    if (methods_is_select(sMethod[id])) {
      if (selectedRowKeys.indexOf(id) < 0) {
        setSelectedRowKeys(selectedRowKeys.concat([id]))
      }
    } else {
      let i = selectedRowKeys.indexOf(id);
      if (i >= 0) {
        selectedRowKeys.splice(i, 1)
        setSelectedRowKeys(selectedRowKeys.concat([]))
      }
    }
    setsMethod({ ...sMethod })
  }
  return (
    <ModalForm
      title={`${data?.name} 分配资源`}
      open={data !== null}
      width={800}
      autoFocusFirstInput
      modalProps={{
        destroyOnClose: true,
        onCancel: onClose,
      }}
      submitTimeout={2000}
      loading={updating}
      onFinish={update}
    >
      <ResultWrap error={error} reload={() => data && loadRoleResourceList(data.id)}>
        <Table
          dataSource={resources ? resources[0] : []}
          loading={loading}
          pagination={false}
          rowKey="id"
          rowSelection={{
            selectedRowKeys: selectedRowKeys,
            onChange(r, rows, info) {
              if (info.type == "all") {
                let selectedMethod: ResourceSelect = {}
                rows.forEach(({ id }) => {
                  selectedMethod[id] = allMethod
                })
                setsMethod(selectedMethod);
              }
              setSelectedRowKeys(r as number[]);
            },
            onSelect(r, v) {
              sMethod[r.id] = { get: v, put: v, post: v, delete: v };
              setsMethod({ ...sMethod })
            }
          }}
        >
          <Table.Column title="资源路径" dataIndex="path" render={(v, record) =>
            <Tooltip title={record.description}>{v}{!record.status && <Tag color="error" bordered={false}>停用</Tag>}</Tooltip>} />
          <Table.Column
            title="请求方法"
            dataIndex="id"
            width={280}
            render={(id: number) => [
              <Tag.CheckableTag checked={sMethod[id]?.get} onChange={(v) => { click_method(id, v, "get") }}>GET</Tag.CheckableTag>,
              <Tag.CheckableTag checked={sMethod[id]?.post} onChange={(v) => { click_method(id, v, "post") }}>POST</Tag.CheckableTag>,
              <Tag.CheckableTag checked={sMethod[id]?.put} onChange={(v) => { click_method(id, v, "put") }}>PUT</Tag.CheckableTag>,
              <Tag.CheckableTag checked={sMethod[id]?.delete} onChange={(v) => { click_method(id, v, "delete") }}>DELETE</Tag.CheckableTag>,
            ]}
          ></Table.Column>
        </Table>
      </ResultWrap>
    </ModalForm>
  );
};

export default RoleResourceForm;
